"""
Logging Configuration System
===========================

Core logging configuration with environment-based profiles.
"""

import os
import sys
import logging
import logging.config
from pathlib import Path
from typing import Dict, Any, Optional
import yaml


# Logging profiles for different environments
LOGGING_PROFILES = {
    'development': {
        'console_level': 'DEBUG',
        'file_level': 'DEBUG',
        'performance_logging': True,
        'websocket_content_logging': True,
        'audio_frame_logging': False
    },
    'production': {
        'console_level': 'INFO', 
        'file_level': 'INFO',
        'performance_logging': True,
        'websocket_content_logging': False,
        'audio_frame_logging': False
    },
    'debug': {
        'console_level': 'DEBUG',
        'file_level': 'DEBUG', 
        'performance_logging': True,
        'websocket_content_logging': True,
        'audio_frame_logging': True
    }
}


def get_logging_config(profile: str = 'production') -> Dict[str, Any]:
    """Generate logging configuration based on profile."""
    
    profile_settings = LOGGING_PROFILES.get(profile, LOGGING_PROFILES['production'])
    
    # Determine the correct base directory for logs
    # For PyInstaller executables, use the directory containing the executable
    # For development, use the script directory
    if getattr(sys, 'frozen', False):
        # Running in PyInstaller bundle
        base_dir = Path(sys.executable).parent
    else:
        # Running as script
        base_dir = Path.cwd()
    
    # Ensure logs directory exists relative to the base directory
    logs_dir = base_dir / 'logs'
    logs_dir.mkdir(exist_ok=True)
    
    config = {
        'version': 1,
        'disable_existing_loggers': False,
        
        'formatters': {
            'detailed': {
                'format': '[{asctime}] {levelname:8} | {name:20} | {funcName:15} | {message}',
                'style': '{',
                'datefmt': '%Y-%m-%d %H:%M:%S'
            },
            'simple_json': {
                'format': '[{asctime}] {levelname} | {name} | {funcName} | {message}',
                'style': '{',
                'datefmt': '%Y-%m-%d %H:%M:%S'
            },
            'console': {
                'format': '[{asctime}] {levelname:8} | {name:15} | {message}',
                'style': '{',
                'datefmt': '%Y-%m-%d %H:%M:%S'
            }
        },
        
        'handlers': {
            'console': {
                'class': 'logging.StreamHandler',
                'level': profile_settings['console_level'],
                'formatter': 'console',
                'stream': 'ext://sys.stdout'
            },
            'file_all': {
                'class': 'logging.handlers.RotatingFileHandler',
                'level': profile_settings['file_level'],
                'formatter': 'detailed',
                'filename': str(logs_dir / 'capswriter.log'),
                'maxBytes': 10485760,  # 10MB
                'backupCount': 10,
                'encoding': 'utf-8'
            },
            'file_errors': {
                'class': 'logging.handlers.RotatingFileHandler',
                'level': 'ERROR',
                'formatter': 'simple_json',
                'filename': str(logs_dir / 'errors.log'),
                'maxBytes': 5242880,   # 5MB 
                'backupCount': 5,
                'encoding': 'utf-8'
            }
        },
        
        'loggers': {
            'capswriter.server.websocket': {
                'level': 'DEBUG',
                'handlers': ['console', 'file_all'],
                'propagate': False
            },
            'capswriter.server.recognition': {
                'level': 'INFO',
                'handlers': ['console', 'file_all'],
                'propagate': False
            },
            'capswriter.client.input': {
                'level': 'INFO', 
                'handlers': ['console', 'file_all'],
                'propagate': False
            },
            'capswriter.client.network': {
                'level': 'INFO',
                'handlers': ['console', 'file_all'], 
                'propagate': False
            },
            'capswriter.system.health': {
                'level': 'INFO',
                'handlers': ['file_all'],
                'propagate': False
            }
        },
        
        'root': {
            'level': 'INFO',
            'handlers': ['console', 'file_all', 'file_errors']
        }
    }
    
    # Add performance logging if enabled
    if profile_settings['performance_logging']:
        config['handlers']['file_performance'] = {
            'class': 'logging.handlers.RotatingFileHandler',
            'level': 'INFO',
            'formatter': 'simple_json',
            'filename': str(logs_dir / 'performance.log'), 
            'maxBytes': 10485760,
            'backupCount': 3,
            'encoding': 'utf-8'
        }
        
        config['loggers']['capswriter.performance'] = {
            'level': 'INFO',
            'handlers': ['file_performance'],
            'propagate': False
        }
    
    return config


def setup_logging(profile: Optional[str] = None) -> None:
    """Setup logging system with specified profile."""
    
    # Determine profile from environment or default
    if profile is None:
        profile = os.environ.get('CAPSWRITER_LOG_PROFILE', 'production')
    
    # Get and apply configuration
    config = get_logging_config(profile)
    
    try:
        logging.config.dictConfig(config)
        
        # Log setup completion
        logger = logging.getLogger('capswriter.logging')
        logger.info(f"Logging system initialized with profile: {profile}")
        
    except Exception as e:
        # Fallback to basic logging if configuration fails
        logging.basicConfig(
            level=logging.INFO,
            format='[%(asctime)s] %(levelname)-8s | %(name)s | %(message)s',
            datefmt='%Y-%m-%d %H:%M:%S'
        )
        
        logger = logging.getLogger('capswriter.logging')
        logger.error(f"Failed to configure logging: {e}")
        logger.info("Using fallback basic logging configuration")


def get_logger(name: str) -> logging.Logger:
    """Get a logger with the specified name."""
    return logging.getLogger(name)


def set_log_level(logger_name: str, level: str) -> None:
    """Dynamically change log level for a specific logger."""
    logger = logging.getLogger(logger_name)
    logger.setLevel(getattr(logging, level.upper()))
    
    # Log the change
    logger.info(f"Log level changed to {level.upper()}")


def save_logging_config(profile: str, filename: str = 'logging_config.yaml') -> None:
    """Save current logging configuration to YAML file."""
    config = get_logging_config(profile)
    
    with open(filename, 'w', encoding='utf-8') as f:
        yaml.dump(config, f, default_flow_style=False, indent=2)


def load_logging_config_from_file(filename: str) -> None:
    """Load logging configuration from YAML file."""
    try:
        # Handle both absolute and relative paths
        if not Path(filename).is_absolute():
            # For relative paths, resolve based on executable/script location
            if getattr(sys, 'frozen', False):
                base_dir = Path(sys.executable).parent
            else:
                base_dir = Path.cwd()
            filename = str(base_dir / filename)
        
        with open(filename, 'r', encoding='utf-8') as f:
            config = yaml.safe_load(f)
        
        logging.config.dictConfig(config)
        
        logger = logging.getLogger('capswriter.logging')
        logger.info(f"Logging configuration loaded from {filename}")
        
    except Exception as e:
        logger = logging.getLogger('capswriter.logging') 
        logger.error(f"Failed to load logging config from {filename}: {e}")